package com.test.typeGame.core;

import com.test.typeGame.TypeGameApp;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.Iterator;
import java.util.Vector;

public class TGLevelObject {
    private TGAudioPlayer tgAudioPlayer = new TGAudioPlayer();

    private Point curScorePoint =  new Point(55,40);
    private Point curMissPoint = new Point(140,40);
    private Point curTypeErrorPoint = new Point(55,curScorePoint.y + 60);
    private Point scorePoint = new Point(curScorePoint.x,curScorePoint.y - 20);
    private Point missPoint = new Point(curMissPoint.x,curMissPoint.y - 20);
    private Point typeErrorPoint = new Point(curTypeErrorPoint.x,curTypeErrorPoint.y - 20);

    private boolean isRun = false;

    private int level = 0;
    private String levelName = "";
    private int passScore = 0;
    private int failScore = 0;
    private int bigDuaring = 5;
    private int scoreBigDuaring = 0;
    private int missBigDuaring = 0;
    private int typeErrorBigDuaring = 0;
    private int curScore = 0;
    private int curMiss = 0;
    private int curTypeError = 0;
    private int lastY = 400;
    private StringBuffer lastLine = new StringBuffer();
    private StringBuffer leftLine = new StringBuffer();
    private StringBuffer rightLine = new StringBuffer();
    private int leftLineX = 160;
    private int rightLineX = 800 - leftLineX;

    private int dataOnceNumber = 1;//每次数量
    private Vector<TGCharObject> levelData = new Vector<TGCharObject>();

    private Vector<Character> characterVector = new Vector<Character>();
    private int characterVectorCurReadIndex = 0;

    private Vector<TGScoreTarget> tgScoreTargetVector = new Vector<TGScoreTarget>();
    private Vector<TGScoreTarget> tgMissScoreTargetVector = new Vector<TGScoreTarget>();
    private Vector<TGScoreTarget> tgTypeErrorTargetVector = new Vector<TGScoreTarget>();

    //汉字
    private Vector<TGZhCharObject> zhChaLevelData = new Vector<TGZhCharObject>();
    private boolean isCharLevel = true;

    int randomDataIndex = 1;
    int randomCharIndex = -1;
    int stepYIndex = -1;

    public void setCharLevel(boolean isCharLevel){
        this.isCharLevel = isCharLevel;
    }

    public TGLevelObject(){
        this(0, "说明",0, 100, 10, 400);
    }
    public TGLevelObject(int level, String levelName){
        this(level, levelName,(level==0?0:1), 100, 10, 400);
    }
    public TGLevelObject(int level, String levelName,int dataOnceNumber){
        this(level, levelName,dataOnceNumber, 100, 10, 400);
    }
    public TGLevelObject(int level, String levelName,int dataOnceNumber, int passScore, int failScore, int lastY){
        for (int i = 0; i < 800; i++){
            lastLine.append("-");
        }
        leftLine.append("|");
        rightLine.append("|");

        clearNextCList();
        this.setLevel(level, levelName,dataOnceNumber, passScore, failScore, lastY);
    }

    public void clear(){
        characterVectorCurReadIndex = 0;
        curScore = 0;
        curMiss = 0;
        curTypeError = 0;
        scoreBigDuaring = 0;
        missBigDuaring = 0;
        typeErrorBigDuaring = 0;
        tgScoreTargetVector.clear();
        tgMissScoreTargetVector.clear();
        tgTypeErrorTargetVector.clear();
        stepYIndex = -1;
        randomCharIndex = -1;
        randomDataIndex = 1;
        isCharLevel = true;
    }

    public void init(){
        levelData.clear();
        for (int i = 0; i < this.dataOnceNumber; i++){
            TGCharObject tgCharObject = new TGCharObject();
            nextC(tgCharObject);
            levelData.add(tgCharObject);
        }

        zhChaLevelData.clear();
        TGZhCharObject tgZhCharObject = new TGZhCharObject();
        tgZhCharObject.setRandomDataIndex(this.randomDataIndex);
        NextData(tgZhCharObject);
        zhChaLevelData.add(tgZhCharObject);
    }

    public void setIsRun(boolean isRun){
        this.isRun = isRun;
    }

    public boolean getIsRun(){
        return this.isRun;
    }

    public void setLevel(int level, String levelName){
        this.setLevel(level, levelName,this.dataOnceNumber, this.passScore, this.failScore, this.lastY);
    }

    public void setLevel(int level, String levelName, int passScore, int failScore){
        this.setLevel(level, levelName, this.dataOnceNumber,passScore, failScore, this.lastY);
    }

    public void setLevel(int level, String levelName,int dataOnceNumber, int passScore, int failScore){
        this.setLevel(level, levelName, dataOnceNumber,passScore, failScore, this.lastY);
    }

    public void setLevel(int level, String levelName,int dataOnceNumber, int passScore, int failScore, int lastY){
        this.level = level;
        this.levelName = levelName;
        this.dataOnceNumber = dataOnceNumber;
        this.passScore = passScore;
        this.failScore = failScore;
        this.lastY = lastY;
    }

    public void restart(){
        isRun = true;
        clear();
        init();
    }


    public void stop(){
        isRun = true;
        clear();
    }

    public Vector<TGCharObject> getLevelData(){
        return levelData;
    }

    public Vector<TGCharObject> getLevelDataNext(){
        return levelData;
    }

    public void setDataOnceNumber(int dataOnceNumber){
        this.dataOnceNumber = dataOnceNumber;
    }
    public int getDataOnceNumber(){
        return dataOnceNumber;
    }

    public String getDataOnceNumberName(){
        return "每次"+dataOnceNumber+"个字符下落";
    }

    //true游戏继续,false游戏结束
    public boolean draw(Graphics g){
        if (isPass()){
            g.setColor(Color.green);
            g.setFont(new Font("TimesRoman", Font.PLAIN, 30));
            g.drawString("恭喜你，通关!",300,300);
            return false;
        }else if(isGameOver()){
            g.setColor(Color.RED);
            g.setFont(new Font("TimesRoman", Font.PLAIN, 30));
            g.drawString("错过"+failScore+"个，游戏结束!",300,300);
            return false;
        }

        if (isRun){
            if (isCharLevel == true) {
                for (TGCharObject iter : levelData
                ) {
                    drawSingeCharObject(g, iter);
                }
            }else{
                for (TGZhCharObject iter:zhChaLevelData
                     ) {
                    drawSingZhCharObject(g,iter);
                }
            }
            drawScoreTarget(g, tgScoreTargetVector);
            drawScoreTarget(g, tgMissScoreTargetVector);
            drawScoreTarget(g, tgTypeErrorTargetVector);

            g.setColor(Color.blue);
            g.setFont(new Font("TimesRoman", Font.PLAIN, 5));
            g.drawString(lastLine.toString(),0, lastY);

            for (int i = 1; i <= lastY;i++){
                g.drawString(leftLine.toString(),leftLineX,i);
                g.drawString(rightLine.toString(),rightLineX,i);
            }

            g.setColor(Color.green);
            g.setFont(new Font("TimesRoman", Font.PLAIN, 15));
            g.drawString("分数:", curScorePoint.x - 50, curScorePoint.y);
            g.setFont(new Font("TimesRoman", Font.PLAIN, ((isScoreBig() == true)?30:15)));
            g.drawString(""+this.curScore, curScorePoint.x, curScorePoint.y);

            g.setFont(new Font("TimesRoman", Font.PLAIN, 15));
            g.setColor(Color.red);
            g.drawString("错过:", curMissPoint.x - 50, curMissPoint.y);
            g.setFont(new Font("TimesRoman", Font.PLAIN, ((isMissBig() == true)?30:15)));
            g.drawString("" + this.curMiss, curMissPoint.x, curMissPoint.y);

            g.setFont(new Font("TimesRoman", Font.PLAIN, 15));
            g.setColor(Color.red);
            g.drawString("打错:", curTypeErrorPoint.x - 50, curTypeErrorPoint.y);
            g.setFont(new Font("TimesRoman", Font.PLAIN, ((isTypeErrorBig() == true)?30:15)));
            g.drawString("" + this.curTypeError, curTypeErrorPoint.x, curTypeErrorPoint.y);

            g.setColor(Color.green);
            g.setFont(new Font("TimesRoman", Font.PLAIN, 15));
            g.drawString("[第" + this.level+"关]"+this.levelName+","+getDataOnceNumberName(), 10, lastY+20);

            g.setColor(Color.green);
            g.setFont(new Font("TimesRoman", Font.PLAIN, 15));
            g.drawString("通关条件，分数到达"+this.passScore+"分；失败条件，错误"+this.failScore+"个。", 10, lastY+40);
        }
        return true;
    }

    private void drawSingeCharObject(Graphics g, TGCharObject charObject){
        g.setFont(charObject.getFont());
        g.setColor(charObject.getCharColor());
        g.drawString(new Character(charObject.getC()).toString(), charObject.getX(), charObject.getY());
        g.setFont(charObject.getIndexNameFont());
        g.drawString(charObject.getIndexName(), charObject.getX()+charObject.getFont().getSize(), charObject.getY());
    }

    private void drawSingZhCharObject(Graphics g, TGZhCharObject tgZhCharObject){
        g.setFont(tgZhCharObject.getFont());
        g.setColor(tgZhCharObject.getCharColor());
        g.drawString(tgZhCharObject.getData(), tgZhCharObject.getX(), tgZhCharObject.getY());
        g.setFont(tgZhCharObject.getIndexNameFont());
        g.drawString(tgZhCharObject.getIndexName(), tgZhCharObject.getX()+tgZhCharObject.getFont().getSize(), tgZhCharObject.getY());
    }

    public boolean isScoreBig(){
        if (scoreBigDuaring == 0){
            return false;
        }else{
            scoreBigDuaring--;
            return true;
        }
    }

    public boolean isMissBig(){
        if (missBigDuaring == 0){
            return false;
        }else{
            missBigDuaring--;
            return true;
        }
    }

    public boolean isTypeErrorBig(){
        if (typeErrorBigDuaring == 0){
            return false;
        }else{
            typeErrorBigDuaring--;
            return true;
        }
    }

    public void addScore(){
        curScore += 1;
        scoreBigDuaring = bigDuaring;
        tgAudioPlayer.playVoiceOfAddScore();
    }

    public void addMiss(){
        curMiss += 1;
        missBigDuaring = bigDuaring;
    }

    public void addTypeError(){
        curTypeError += 1;
        typeErrorBigDuaring = bigDuaring;
    }

    public void runDown(){
        if (true == isCharLevel){
        for (TGCharObject iter:levelData
             ) {
            iter.runDown();
            if (iter.getY() >= this.lastY){
                addMiss();
                addMissScoreTarget();
                nextC(iter);
            }
        }
        }else{
            //汉字
            for (TGZhCharObject iter:zhChaLevelData
                 ) {
                iter.runDown();
                if (iter.getY() >= this.lastY){
                    addMiss();
                    addMissScoreTarget();
                    iter.nextData(this.randomDataIndex);
                }
            }
        }

        for (TGScoreTarget iter:tgScoreTargetVector
             ) {
            iter.runToTarget();
        }

        for (TGScoreTarget iter:tgMissScoreTargetVector
             ) {
            iter.runToTarget();
        }

        for (TGScoreTarget iter:tgTypeErrorTargetVector){
            iter.runToTarget();
        }
    }

    //处理汉字
    public void dealZhChar(String data){
        if (null == data || data.trim().equals("")){
            return ;
        }
        boolean bTypeError = true;
        for (TGZhCharObject iter:zhChaLevelData
             ) {
            if (iter.checkEquel(data)){
                addScore();
                addScoreTarget();
                bTypeError = false;
                iter.setStepYIndex(this.stepYIndex);
                iter.nextData(this.randomDataIndex);
            }
        }
        if(true == bTypeError){
            addTypeErrorScoreTarget();
            addTypeError();
        }
    }

    //处理字符
    public void dealPressed(KeyEvent e){
        char typeC = e.getKeyChar();
        int typeCode = e.getKeyCode();
        if (isRun && true == isCharLevel) {
            boolean bTypeError = true;
            for (int i = 0; i < levelData.size(); i++) {
                if (typeC == levelData.get(i).getC()) {
                    addScoreTarget();
                    addScore();
                    bTypeError = false;
                    nextC(levelData.get(i));
                }
            }
            if(16 != typeCode && true == bTypeError){
                addTypeErrorScoreTarget();
                addTypeError();
            }
        }
    }

    public void nextC(TGCharObject tgCharObject){
        tgCharObject.setStepYIndex(this.stepYIndex);
        if (characterVector.size() > 0) {
            if (characterVectorCurReadIndex >= characterVector.size()){
                characterVectorCurReadIndex = 0;
            }
            tgCharObject.nextC(characterVector.get(characterVectorCurReadIndex));
            characterVectorCurReadIndex++;
        }else if(randomCharIndex != -1){
            tgCharObject.nextC(randomCharIndex);
        }else{
            tgCharObject.nextC();
        }

    }

    public void NextData(TGZhCharObject tgZhCharObject){
        tgZhCharObject.nextData(this.randomDataIndex);
    }

    public void clearNextCList(){
        characterVectorCurReadIndex = 0;
        characterVector.clear();
    }
    //按list获取nextC
    public void setNextCList(Vector<Character> chVector){
        characterVectorCurReadIndex = 0;
        characterVector.clear();
        for (Character c:chVector
             ) {
            characterVector.add(c);
        }
    }

    //1小写，2大写，3数字
    void setRandomCharIndex(int index){
        randomCharIndex = index;
    }
    void setRandomDataIndex(int index){
        this.randomDataIndex = index;
    }

    void setStepYIndex(int stepYIndex){
        this.stepYIndex = stepYIndex;
    }

    //true为通关
    public boolean isPass(){
        if (curScore >= passScore){
            isRun = false;
            return true;
        }else{
            return false;
        }
    }

    //true为游戏结束
    public boolean isGameOver(){
        if (curMiss >= failScore){
            isRun = false;
            return true;
        }else{
            return false;
        }
    }

    public synchronized void addScoreTarget(){
        TGScoreTarget tgScoreTarget = new TGScoreTarget();
        tgScoreTarget.setColor(Color.GREEN);
        tgScoreTarget.setTargetXY(scorePoint.x,scorePoint.y - 40);
        tgScoreTarget.setStepXY(0,-1);
        tgScoreTarget.setXY(scorePoint.x, scorePoint.y);
        tgScoreTargetVector.add(tgScoreTarget);
    }

    public synchronized void addMissScoreTarget(){
        TGScoreTarget tgMissScoreTarget = new TGScoreTarget();
        tgMissScoreTarget.setColor(Color.RED);
        tgMissScoreTarget.setTargetXY(missPoint.x,missPoint.y - 40);
        tgMissScoreTarget.setStepXY(0,-1);
        tgMissScoreTarget.setXY(missPoint.x, missPoint.y);
        tgMissScoreTargetVector.add(tgMissScoreTarget);
    }

    public synchronized void addTypeErrorScoreTarget(){
        TGScoreTarget tgTypeErrorScoreTarget = new TGScoreTarget();
        tgTypeErrorScoreTarget.setColor(Color.RED);
        tgTypeErrorScoreTarget.setTargetXY(typeErrorPoint.x,typeErrorPoint.y - 40);
        tgTypeErrorScoreTarget.setStepXY(0,-1);
        tgTypeErrorScoreTarget.setXY(typeErrorPoint.x, typeErrorPoint.y);
        tgTypeErrorTargetVector.add(tgTypeErrorScoreTarget);
    }

    public void drawScoreTarget(Graphics g, Vector<TGScoreTarget> tgScoreTargets){
        Iterator<TGScoreTarget> iterator = tgScoreTargets.iterator();
        while (iterator.hasNext()){
            TGScoreTarget tgScoreTarget = iterator.next();
            if (tgScoreTarget.isOnTarget()){
                iterator.remove();
            }else{
                g.setFont(tgScoreTarget.getFont());
                g.setColor(tgScoreTarget.getColor());
                g.drawString(tgScoreTarget.getData(),tgScoreTarget.getX(), tgScoreTarget.getY());
            }
        }
    }
}
